﻿using System;
using System.Collections.Generic;
using System.Linq;
using Translate.Pages;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media.Animation;
using Windows.UI.Xaml.Navigation;

// https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x804 上介绍了“空白页”项模板

namespace Translate {
    /// <summary>
    /// 可用于自身或导航至 Frame 内部的空白页。
    /// </summary>
    public sealed partial class MainPage : Page {
        public MainPage() {
            InitializeComponent();
        }

        private double NavViewCompactModeThresholdWidth { get { return NavView.CompactModeThresholdWidth; } }

        
        // List of ValueTuple holding the Navigation Tag and the relative Navigation Page
        private readonly List<(string Tag, Type Page)> _pages =
            new List<(string Tag, Type Page)> { ("home", typeof(HomePage)), };
        private void NavView_Loaded(object sender, RoutedEventArgs e) {
            NavView.MenuItems.Add(new NavigationViewItem {
                Content = "Words Book",
                Icon = new SymbolIcon((Symbol)0xEB3C),
                Tag = "wordsBook"
            });
            _pages.Add(("wordsBook", typeof(WordsBookPage)));
            // 添加分隔线
            NavView.MenuItems.Add(new NavigationViewItemSeparator());

            NavView.MenuItems.Add(new NavigationViewItem {
                Content = "My content",
                Icon = new SymbolIcon((Symbol)0xF1AD),
                Tag = "content"
            });
            _pages.Add(("content", typeof(MyContentPage)));

            NavViewAddMenuItem("Show Data", typeof(ShowDataPage));

            // Add handler for ContentFrame navigation.
            ContentFrame.Navigated += On_Navigated;

            // NavView doesn't load any page by default, so load home page.
            // NavView默认不加载任何页面，所以加载主页。
            NavView.SelectedItem = NavView.MenuItems[0];

            // If navigation occurs on SelectionChanged, this isn't needed.
            // Because we use ItemInvoked to navigate, we need to call Navigate
            // here to load the home page.
            NavView_Navigate("home", new Windows.UI.Xaml.Media.Animation.EntranceNavigationTransitionInfo());

            // Add keyboard accelerators for backwards navigation.
            // 为向后导航添加键盘快捷键。
            KeyboardAccelerator goBack = new KeyboardAccelerator { Key = Windows.System.VirtualKey.GoBack };
            goBack.Invoked += BackInvoked;
            KeyboardAccelerators.Add(goBack);

            // ALT routes here
            KeyboardAccelerator altLeft = new KeyboardAccelerator {
                Key = Windows.System.VirtualKey.Left,
                Modifiers = Windows.System.VirtualKeyModifiers.Menu
            };
            altLeft.Invoked += BackInvoked;
            KeyboardAccelerators.Add(altLeft);

            void NavViewAddMenuItem(string content, Type type, string tag = null, Symbol iconSymbol = (Symbol)0xF1AD) {
                tag = (tag ?? content).Replace(" ", "").ToLower();
                NavView.MenuItems.Add(new NavigationViewItem {
                    Content = content,
                    Icon = new SymbolIcon(iconSymbol),
                    Tag = tag
                });
                _pages.Add((tag, type));
            }
        }

        // NavView_SelectionChanged is not used in this example, but is shown for completeness.
        // You will typically handle either ItemInvoked or SelectionChanged to perform navigation,
        // but not both.
        private void NavView_SelectionChanged(NavigationView sender,
                                              NavigationViewSelectionChangedEventArgs args) {
            if (args.IsSettingsSelected == true) {
                NavView_Navigate("settings", args.RecommendedNavigationTransitionInfo);
            } else if (args.SelectedItemContainer != null) {
                var navItemTag = args.SelectedItemContainer.Tag.ToString();
                NavView_Navigate(navItemTag, args.RecommendedNavigationTransitionInfo);
            }
        }

        private void BackInvoked(KeyboardAccelerator sender, KeyboardAcceleratorInvokedEventArgs args) {
            On_BackRequested();
            args.Handled = true;
        }

        private void NavView_ItemInvoked(NavigationView sender, NavigationViewItemInvokedEventArgs args) {
            if (args.IsSettingsInvoked == true) {
                NavView_Navigate("settings", args.RecommendedNavigationTransitionInfo);
            } else if (args.InvokedItemContainer != null) {
                string navItemTag = args.InvokedItemContainer.Tag.ToString();
                NavView_Navigate(navItemTag, args.RecommendedNavigationTransitionInfo);
            }
        }

        private void NavView_Navigate(string navItemTag,
                                     NavigationTransitionInfo transitionInfo) {
            Type _page = null;
            if (navItemTag == "settings") {
                _page = typeof(SettingsPage);
            }
            else {
                var item = _pages.FirstOrDefault(p => p.Tag.Equals(navItemTag));
                _page = item.Page;
            }

            // Get the page type before navigation so you can prevent duplicate
            // entries in the backstack.
            // 在导航之前获取页面类型，这样可以防止在 backstack 中出现重复。
            var preNavPageType = ContentFrame.CurrentSourcePageType;

            // Only navigate if the selected page isn't currently loaded.
            // 仅在当前未加载所选页面时进行导航。
            if (!(_page is null) && !Type.Equals(preNavPageType, _page)) {
                ContentFrame.Navigate(_page, null, transitionInfo);
            }
        }
        private void NavView_BackRequested(NavigationView sender, NavigationViewBackRequestedEventArgs args) {
            On_BackRequested();
        }

        private bool On_BackRequested() {
            if (!ContentFrame.CanGoBack) {
                return false;
            }
            // Don't go back if the nav pane is overlayed.
            if (NavView.IsPaneOpen &&
                (NavView.DisplayMode == NavigationViewDisplayMode.Compact ||
                 NavView.DisplayMode == NavigationViewDisplayMode.Minimal))
                return false;

            ContentFrame.GoBack();
            return true;
        }

        private void ContentFrame_NavigationFailed(object sender, NavigationFailedEventArgs e) {
            throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
        }

        private void On_Navigated(object sender, NavigationEventArgs e) {
            NavView.IsBackEnabled = ContentFrame.CanGoBack;

            if (ContentFrame.SourcePageType == typeof(SettingsPage)) {
                // SettingsItem is not part of NavView.MenuItems, and doesn't have a Tag.
                NavView.SelectedItem = (NavigationViewItem)NavView.SettingsItem;
                NavView.Header = "Settings";
            }
            else if (ContentFrame.SourcePageType != null) {
                var item = _pages.FirstOrDefault(p => p.Page == e.SourcePageType);

                NavView.SelectedItem = NavView.MenuItems
                    .OfType<NavigationViewItem>()
                    .First(n => n.Tag.Equals(item.Tag));

                NavView.Header =
                    ((NavigationViewItem)NavView.SelectedItem)?.Content?.ToString();
            }
        }
    }
}
